package utils

import (
	"github.com/mozillazg/go-pinyin"
	"strings"
)

// GetPingYin 获取首字母拼音
func GetPingYin(name string) string {
	args := pinyin.NewArgs()
	args.Style = pinyin.FirstLetter
	return strings.Replace(pinyin.Slug(name, args), "-", "", -1)
}

// GetFullPingYin 获取完整拼音
func GetFullPingYin(name string) string {
	args := pinyin.NewArgs()
	args.Style = pinyin.Normal
	return strings.Replace(pinyin.Slug(name, args), "-", "", -1)
}

// GetPingYinWithTone 获取带声调的拼音
func GetPingYinWithTone(name string) string {
	args := pinyin.NewArgs()
	args.Style = pinyin.Tone
	return strings.Replace(pinyin.Slug(name, args), "-", "", -1)
}

// MatchPinyin 智能拼音匹配，支持多种匹配方式
func MatchPinyin(text, keyword string) (bool, int) {
	if text == "" || keyword == "" {
		return false, 0
	}
	
	// 预先转换为小写，避免重复转换
	textLower := strings.ToLower(text)
	keywordLower := strings.ToLower(keyword)
	
	// 0. 特殊应用别名匹配（最高优先级）
	if matched, score := matchAppAlias(textLower, keywordLower); matched {
		return true, score
	}
	
	// 1. 直接文本匹配（最高优先级）- 最快的匹配方式
	if strings.Contains(textLower, keywordLower) {
		if textLower == keywordLower {
			return true, 100 // 完全匹配
		} else if strings.HasPrefix(textLower, keywordLower) {
			return true, 90 // 前缀匹配
		} else {
			return true, 80 // 包含匹配
		}
	}
	
	// 2. 英文首字母匹配（针对英文应用名）- 快速检查
	if isEnglishText(textLower) { // 使用已转换的小写文本
		if matchEnglishInitials(textLower, keywordLower) {
			return true, 75
		}
	}
	
	// 3. 混合中英文处理 - 只在必要时执行
	if containsChinese(text) && containsEnglish(textLower) {
		if matchMixedText(textLower, keywordLower) {
			return true, 72
		}
	}
	
	// 4. 拼音匹配 - 延迟到最后，因为比较耗时
	// 只有在前面的快速匹配都失败时才进行拼音匹配
	if containsChinese(text) {
		// 首字母拼音匹配
		firstLetterPinyin := GetPingYin(text)
		keywordFirstLetter := GetPingYin(keyword)
		
		if firstLetterPinyin != "" && keywordFirstLetter != "" && strings.Contains(firstLetterPinyin, keywordFirstLetter) {
			if firstLetterPinyin == keywordFirstLetter {
				return true, 70 // 首字母完全匹配
			} else if strings.HasPrefix(firstLetterPinyin, keywordFirstLetter) {
				return true, 60 // 首字母前缀匹配
			} else {
				return true, 50 // 首字母包含匹配
			}
		}
		
		// 完整拼音匹配
		fullPinyin := GetFullPingYin(text)
		keywordFullPinyin := GetFullPingYin(keyword)
		
		if fullPinyin != "" && keywordFullPinyin != "" && strings.Contains(fullPinyin, keywordFullPinyin) {
			if fullPinyin == keywordFullPinyin {
				return true, 65 // 完整拼音匹配
			} else if strings.HasPrefix(fullPinyin, keywordFullPinyin) {
				return true, 55 // 完整拼音前缀匹配
			} else {
				return true, 45 // 完整拼音包含匹配
			}
		}
		
		// 混合匹配：关键词拼音在文本中的匹配
		if fullPinyin != "" && strings.Contains(fullPinyin, keywordLower) {
			return true, 40 // 拼音包含原始关键词
		}
		
		// 模糊匹配：支持部分拼音输入
		if len(keywordLower) >= 2 && firstLetterPinyin != "" && len(keywordLower) <= len(firstLetterPinyin) {
			match := true
			for i := 0; i < len(keywordLower); i++ {
				if keywordLower[i] != firstLetterPinyin[i] {
					match = false
					break
				}
			}
			if match {
				return true, 30
			}
		}
	}
	
	return false, 0
}

// matchAppAlias 匹配应用别名
func matchAppAlias(textLower, keywordLower string) (bool, int) {
	// 定义应用别名映射
	aliases := map[string][]string{
		"微信": {"wechat", "weixin", "wx"},
		"wechat": {"微信", "weixin", "wx"},
		"计算器": {"calculator", "calc", "jisuanqi"},
		"calculator": {"计算器", "calc", "jisuanqi"},
		"日历": {"calendar", "rili"},
		"calendar": {"日历", "rili"},
		"邮件": {"mail", "youjian"},
		"mail": {"邮件", "youjian"},
		"safari浏览器": {"safari", "browser", "liulanqi"},
		"safari": {"safari浏览器", "browser", "liulanqi"},
		"备忘录": {"notes", "beiwanglu"},
		"notes": {"备忘录", "beiwanglu"},
		"访达": {"finder", "fangdaqi"},
		"finder": {"访达", "fangdaqi"},
		"visual studio code": {"vscode", "vs code", "code"},
		"vscode": {"visual studio code", "vs code"},
	}
	
	// 检查文本是否匹配任何别名
	if aliasNames, exists := aliases[textLower]; exists {
		for _, alias := range aliasNames {
			if strings.Contains(alias, keywordLower) {
				if alias == keywordLower {
					return true, 95 // 别名完全匹配
				} else if strings.HasPrefix(alias, keywordLower) {
					return true, 85 // 别名前缀匹配
				} else {
					return true, 75 // 别名包含匹配
				}
			}
		}
	}
	
	// 反向检查：关键词是否匹配文本的别名
	if aliasNames, exists := aliases[keywordLower]; exists {
		for _, alias := range aliasNames {
			if strings.Contains(textLower, alias) {
				if textLower == alias {
					return true, 95 // 别名完全匹配
				} else if strings.HasPrefix(textLower, alias) {
					return true, 85 // 别名前缀匹配
				} else {
					return true, 75 // 别名包含匹配
				}
			}
		}
	}
	
	return false, 0
}

// containsChinese 检查文本是否包含中文字符
func containsChinese(text string) bool {
	for _, char := range text {
		if char >= 0x4e00 && char <= 0x9fff {
			return true
		}
	}
	return false
}

// containsEnglish 检查文本是否包含英文字符
func containsEnglish(text string) bool {
	for _, char := range text {
		if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') {
			return true
		}
	}
	return false
}

// matchMixedText 处理混合中英文文本的匹配
func matchMixedText(text, keyword string) bool {
	keywordLower := strings.ToLower(keyword)
	
	// 提取英文部分和中文部分
	var englishPart, chinesePart strings.Builder
	
	for _, char := range text {
		if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') {
			englishPart.WriteRune(char)
		} else if char >= 0x4e00 && char <= 0x9fff {
			chinesePart.WriteRune(char)
		}
	}
	
	// 组合匹配：英文首字母 + 中文拼音首字母
	if englishPart.Len() > 0 && chinesePart.Len() > 0 {
		englishInitials := strings.ToLower(string(englishPart.String()[0]))
		chinesePinyin := GetPingYin(chinesePart.String())
		combined := englishInitials + chinesePinyin
		
		if strings.Contains(combined, keywordLower) {
			return true
		}
	}
	
	return false
}

// isEnglishText 判断文本是否主要为英文 - 优化版本
func isEnglishText(textLower string) bool {
	if len(textLower) == 0 {
		return false
	}
	
	englishChars := 0
	totalChars := 0
	
	// 使用字节遍历，比rune遍历更快
	for i := 0; i < len(textLower); i++ {
		char := textLower[i]
		if char != ' ' && char != '\t' {
			totalChars++
			if (char >= 'a' && char <= 'z') {
				englishChars++
			}
		}
	}
	
	return totalChars > 0 && englishChars*2 > totalChars // 避免浮点运算
}

// matchEnglishInitials 匹配英文单词的首字母 - 优化版本
func matchEnglishInitials(textLower, keywordLower string) bool {
	// 特殊处理：常见的应用名缩写
	if keywordLower == "vscode" && strings.Contains(textLower, "visual studio code") {
		return true
	}
	
	words := strings.Fields(textLower)
	if len(words) == 0 {
		return false
	}
	
	// 快速检查：如果关键词长度超过单词数，不可能匹配首字母
	if len(keywordLower) > len(words) {
		// 但仍然检查单词包含匹配
		for _, word := range words {
			if strings.Contains(word, keywordLower) {
				return true
			}
		}
		return false
	}
	
	// 生成首字母缩写 - 使用字节数组避免字符串拼接
	initials := make([]byte, 0, len(words))
	for _, word := range words {
		if len(word) > 0 {
			initials = append(initials, word[0])
		}
	}
	
	// 检查首字母匹配
	initialsStr := string(initials)
	if strings.Contains(initialsStr, keywordLower) {
		return true
	}
	
	// 单词包含匹配（对于较长的关键词）
	if len(keywordLower) > 2 {
		for _, word := range words {
			if strings.Contains(word, keywordLower) {
				return true
			}
		}
	}
	
	return false
}
